﻿using BigfootDNN.Mvc;
using DotNetNuke.Entities.Modules;

namespace BigfootDNN
{

    /// <summary>
    /// This is the class from which all dnn module setting controls need to inherit. It provides
    /// a series of methods and classes that give you easy access to the different helpers throughout the system
    /// It also provides aliased functions like RenderPartial which is part of the JSHelper for easy access.
    /// </summary>
    public abstract class BaseSettingsControl : ModuleSettingsBase
    {

        /// <summary>
        /// This funciton must be overridden by the inheritor in order to Init the application parameters
        /// </summary>
        public abstract DnnApp InitApp();

        /// <summary>
        /// Returns the application object for the current module
        /// </summary>
        public DnnApp App { get { return _app ?? (_app = InitApp()); } }
        private DnnApp _app;

        /// <summary>
        /// This field is set by the route.renderpartial to indicate to the base view that it is being rendered by it. 
        /// </summary>
        public bool IsRenderPartial;

        /// <summary>
        /// Creates a default route (home/index.ascx). But everything else is fully usable
        /// </summary>
        public RouteInfo Route { get { return _route ?? (_route = new RouteInfo(ModuleConfiguration, App)); } }
        private RouteInfo _route;

        /// <summary>
        /// Inclues all view helper functions (i.e. RenderPartial, E, UrlP, Url, Html, JS, TB, Ajax, CreatePartialForm, SubmitPartialForm, RenderIf, Post values, etc.)
        /// </summary>
        public DnnViewHelper Helper
        {
            get
            {
                return _viewHelper ?? (_viewHelper = new DnnViewHelper(Route, IsRenderPartial));
            }
        }
        private DnnViewHelper _viewHelper;

        /// <summary>
        /// Alias to Helper
        /// </summary>
        public DnnViewHelper BF
        {
            get
            {
                return Helper;
            }
        }
        
        ///// <summary>
        ///// This funciton must be overridden by the inheritor in order to Init the application parameters
        ///// </summary>
        //public abstract DnnApp InitApp();

        ///// <summary>
        ///// Returns the application object for the current module
        ///// </summary>
        //public DnnApp App { get { return _app ?? (_app = InitApp()); } }
        //private DnnApp _app;

        ///// <summary>
        ///// Contains the HTML helpers you can use in the views. It is an alias class that provides easy access to the HTMLHelper class.
        ///// </summary>
        //public class Html : HtmlHelper { }

        ///// <summary>
        ///// Contains the Javascript helpers you can use in the views. It is an alias class that provides easy access to the JSHelper class.
        ///// </summary>
        //public class JS : JSHelper { }

        ///// <summary>
        ///// This is a general purpose html tag builder class. It is an alias class that provides easy access to the HtmlHelper.TagBuilder class.
        ///// </summary>
        //public HtmlHelper.TagBuilder TB(string tagName) { return new HtmlHelper.TagBuilder(tagName); }

        ///// <summary>
        ///// Creates a new AJAX request object you can build on in order to make ajax call to the server
        ///// </summary>
        ///// <param name="url">The url agains which you are executing the ajax request</param>
        //public AjaxRequest Ajax(string url) { return AjaxRequest.Create(url); }

        ///// <summary>
        ///// Creates a partial from. Partial forms are a way to make field groups within a form behave like a form
        ///// for the purposes of validation, and POST.
        ///// </summary>
        ///// <param name="formId">The element id that wraps the field group (i.e. div etc)</param>
        ///// <returns>A script to ouputed on the page</returns>
        //public string CreatePartialForm(string formId) { return JSHelper.CreatePartialForm(formId); }

        ///// <summary>
        ///// Submits a partial from. Partial forms are a way to make field groups "Partial Form" within a form behave like a form
        ///// for the purposes of validation, and POST.
        ///// </summary>
        ///// <param name="formId">The element id that wraps the field group "Partial Form" (i.e. div etc)</param>
        ///// <param name="url">The url you would like to submit the form to</param>
        ///// <returns>AJAX Request object upon which you can build other actions, like clearing the contents of a field upon callback etc.</returns>
        //public AjaxRequest SubmitPartialForm(string formId, string url) { return JSHelper.SubmitPartialForm(formId, url); }

        ///// <summary>
        ///// Submits a partial from. Partial forms are a way to make field groups "Partial Form" within a form behave like a form
        ///// for the purposes of validation, and POST.
        ///// </summary>
        ///// <param name="formId">The element id that wraps the field group "Partial Form" (i.e. div etc)</param>
        ///// <param name="url">The url you would like to submit the form to</param>
        ///// <param name="validate">Determines weather to validate the form before submission or not</param>
        ///// <returns>AJAX Request object upon which you can build other actions, like clearing the contents of a field upon callback etc.</returns>
        //public AjaxRequest SubmitPartialForm(string formId, string url, bool validate) { return JSHelper.SubmitPartialForm(formId, url, validate); }

        ///// <summary>
        ///// A helper builder function that outputs the text only if the specified condition is true
        ///// (i.e. <%=RenderIf(user.HasGrups, user.GroupString)%>
        ///// </summary>
        ///// <param name="condition">The condition that determines weather the text is rendered or not</param>
        ///// <param name="text">The text / html to render if the condition is true </param>
        ///// <returns>Returns the RenderIfBuilder upon which you can further build with an .else statement other if conditions etc.</returns>
        //public HtmlHelper.RenderIfBuilder RenderIf(bool condition, string text) { return Html.RenderIf(condition, text); }

        ///// <summary>
        ///// THIS FIELD IS SET BY THE ROUTE.RENDERPARTIAL TO INDICATE TO THE BASE VIEW THAT IT IS BEING RENDERED BY IT. 
        ///// </summary>
        //public bool IsRenderPartial;

        ///// <summary>
        ///// Render a partial UserControl onto the page
        ///// </summary>
        ///// <param name="viewPath">The relative views path. i.e. home/menu.ascx will be interpreted as ~/desktopmodules/modulename/views/home/menu.ascx</param>
        ///// <returns>The rendered html output of the user control</returns>
        //public string RenderPartial(string viewPath)
        //{
        //    return RenderPartial(viewPath, null);
        //}

        ///// <summary>
        ///// Render a partial UserControl onto the page
        ///// </summary>
        ///// <param name="viewPath">The relative views path. i.e. home/menu.ascx will be interpreted as ~/desktopmodules/modulename/views/home/menu.ascx</param>
        ///// <param name="data">The data to be used as the view's model</param>
        ///// <returns>The rendered html output of the user control</returns>
        //public string RenderPartial(string viewPath, object data)
        //{
        //    try
        //    {
        //        return App.RenderViewToString(App.ViewsPath + viewPath, data, "Route", new RouteInfo("Home", "Index", ModuleConfiguration, App));
        //    }
        //    catch (Exception ex)
        //    {
        //        App.HandleException(ex, false);
        //        return App.RenderViewToString(App.ErrorViewPath, ErrorViewModel.Create(ex, App.Request.Url.ToString()));
        //    }
        //}

        ///// <summary>
        ///// Render a partial view onto the page using the MVC view route method.
        ///// </summary>
        ///// <param name="controllerName">The name of the controller folder that contains the view</param>
        ///// <param name="viewName">The name of the view</param>
        ///// <returns>The rendered html output of the view</returns>
        //public string RenderPartial(string controllerName, string viewName)
        //{
        //    return RenderPartial(RouteHelper.ControlPath(controllerName, viewName, App), null);
        //}

        ///// <summary>
        ///// Render a partial view onto the page using the MVC view route method.
        ///// </summary>
        ///// <param name="controllerName">The name of the controller folder that contains the view</param>
        ///// <param name="viewName">The name of the view</param>
        ///// <param name="data">The data to be used as the view's model</param>
        ///// <returns>The rendered html output of the view</returns>
        //public string RenderPartial(string controllerName, string viewName, object data)
        //{
        //    return RenderPartial(RouteHelper.ControlPath(controllerName, viewName, App), data);
        //}

        ///// <summary>
        ///// Render a partial view onto the page only if the specified condition is met
        ///// </summary>
        ///// <param name="Condition">The condition that must be met in order for the view to be rendered</param>
        ///// <param name="viewPath">The relative views path. i.e. home/menu.ascx will be interpreted as ~/desktopmodules/modulename/views/home/menu.ascx</param>
        ///// <param name="data">The data to be used as the views model</param>
        ///// <returns>The rendered html output of the view</returns>
        //public string RenderPartialIf(bool Condition, string viewPath, object data)
        //{
        //    return Condition ? RenderPartial(viewPath, data) : "";
        //}

        ///// <summary>
        ///// Render a partial view onto the page only if the specified condition is met
        ///// </summary>
        ///// <param name="Condition">The condition that must be met in order for the view to be rendered</param>
        ///// <param name="controllerName">The name of the controller folder that contains the view</param>
        ///// <param name="viewName">The name of the view</param>
        ///// <param name="data">The data to be used as the views model</param>
        ///// <returns>The rendered html output of the view</returns>
        //public string RenderPartialIf(bool Condition, string controllerName, string viewName, object data)
        //{
        //    return Condition ? RenderPartial(RouteHelper.ControlPath(controllerName, viewName, App), data) : "";
        //}

        ///// <summary>
        ///// Render a partial view onto the page only if the specified condition is met
        ///// </summary>
        ///// <param name="Condition">The condition that must be met in order for the view to be rendered</param>
        ///// <param name="controllerName">The name of the controller folder that contains the view</param>
        ///// <param name="viewName">The name of the view</param>
        ///// <returns>The rendered html output of the view</returns>
        //public string RenderPartialIf(bool Condition, string controllerName, string viewName)
        //{
        //    return Condition ? RenderPartial(RouteHelper.ControlPath(controllerName, viewName, App), null) : "";
        //}

        ///// <summary>
        ///// HtmlEncode the string for output
        ///// </summary>
        ///// <param name="data">The string to be encoded</param>
        ///// <returns>HtmlEncoded string</returns>
        //public string E(string data)
        //{
        //    return HttpUtility.HtmlEncode(data);
        //}

        ///// <summary>
        ///// Quick access to the String.Format function
        ///// </summary>
        ///// <param name="value">The string where the values will be inserted i.e. The bird flew {0} miles</param>
        ///// <param name="values">The values to merge with the format string</param>
        ///// <returns>The formated string</returns>
        //public string F(string value, params string[] values)
        //{
        //    return string.Format(value, values);
        //}

        ///// <summary>
        ///// Creates a properly formated url parameter. 
        ///// </summary>
        ///// <param name="paramName">The name of the url parameter</param>
        ///// <param name="value">The value of the url parameter</param>
        ///// <returns>The properly formatted parameter i.e. parameter=value</returns>
        //public string UrlP(string paramName, string value)
        //{
        //    return paramName + "=" + value;
        //}

        ///// <summary>
        ///// Creates a properly formated url parameter. 
        ///// </summary>
        ///// <param name="paramName">The name of the url parameter</param>
        ///// <param name="value">The integer value of the url parameter</param>
        ///// <returns>The properly formatted parameter i.e. parameter=value</returns>
        //public string UrlP(string paramName, int value)
        //{
        //    return paramName + "=" + value;
        //}

        ///// <summary>
        ///// This functions is called from the markup to handle any view error. It has the logic to know weather to output the error to the screen
        ///// or in the case of being partially rendered to raise the error to the RenderView function
        ///// </summary>
        ///// <param name="ex">The exception to be handled</param>
        //public void HandleViewError(Exception ex)
        //{
        //    // If it is rendering in partial mode, then render the error.
        //    if (IsRenderPartial) throw ex;

        //    App.HandleException(ex, false);
        //    Controls.Add(new LiteralControl(RenderPartial("shared", "error", ErrorViewModel.Create(ex, App.Request.Url.ToString()))));
        //}

        ///// <summary>
        ///// Easy access to the UrlBuilder class. Aids in the fluid creation of urls and url parameters
        ///// </summary>
        //public UrlBuilder QS { get { return new UrlBuilder(); } }

        //private UrlHelper _url;
        ///// <summary>
        ///// Creates a new instance of the UrlHelper class to help you create urls
        ///// </summary>
        //public UrlHelper Url
        //{
        //    get { return _url ?? (_url = new UrlHelper("Home", "Index", ModuleConfiguration, App)); }
        //}


        ///// <summary>
        ///// Creates a unique client id specific to this module instance on the page. This is useful when refering to element ids from javascript as
        ///// you might have the same id if the module is added to the page several times. It simply adds an underscore plus the 
        ///// module id to the name
        ///// </summary>
        ///// <param name="id">The id of the element you would like to make unique to the module</param>
        ///// <returns>It returns {id}_{ModuleId}</returns>
        //public string uid(string id)
        //{
        //    return id + "_" + ModuleId;
        //}
    }
}
